package com.gnerv.battle.boot.module.base.business.impl;

import com.gnerv.battle.boot.common.base.exception.BusinessException;
import com.gnerv.battle.boot.common.base.model.RestResult;
import com.gnerv.battle.boot.common.tools.UUIDTools;
import com.gnerv.battle.boot.module.base.business.AccountBusiness;
import com.gnerv.battle.boot.module.base.model.bo.AccountBO;
import com.gnerv.battle.boot.module.base.model.dto.AccountCreateDTO;
import com.gnerv.battle.boot.module.base.model.dto.AccountDTO;
import com.gnerv.battle.boot.module.base.model.dto.AccountRoleDTO;
import com.gnerv.battle.boot.module.base.model.dto.AccountUpdateDTO;
import com.gnerv.battle.boot.module.base.service.AccountService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author Gnerv LiGen
 */
@Slf4j
@Service
@AllArgsConstructor
public class AccountBusinessImpl implements AccountBusiness {

    private final AccountService accountService;

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public RestResult<Void> create(AccountCreateDTO accountCreateDTO) {
        boolean exist = accountService.isExist(accountCreateDTO.getUsername());
        if (exist){
            throw new BusinessException("username already exist");
        }
        String ukId = UUIDTools.lower();
        AccountBO accountBO = accountCreateDTO.toAccountBO();
        accountBO.setUkId(ukId);
        accountService.create(accountBO);
        accountService.bindRole(ukId, accountCreateDTO.getRoleUkIdList());
        return RestResult.ok();
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public RestResult<Void> deleteByUkId(String ukId) {
        accountService.deleteByUkId(ukId);
        accountService.unbindRole(ukId);
        return RestResult.ok();
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public RestResult<Void> updateByUkId(AccountUpdateDTO accountUpdateDTO) {
        AccountBO accountBO = accountUpdateDTO.toAccountBO();
        accountService.updateByUkId(accountBO);
        accountService.unbindRole(accountBO.getUkId());
        accountService.bindRole(accountBO.getUkId(), accountUpdateDTO.getRoleUkIdList());
        return RestResult.ok();
    }

    @Override
    public RestResult<Void> updateRoleByUkId(AccountRoleDTO accountRoleDTO) {
        accountService.bindRole(accountRoleDTO.getAccountUkId(), accountRoleDTO.getRoleUkIdList());
        return RestResult.ok();
    }

    @Override
    @Transactional(readOnly = true)
    public RestResult<AccountDTO> selectByUkId(String ukId) {
        return RestResult.ok(accountService.selectByUkId(ukId));
    }

    @Override
    @Transactional(readOnly = true)
    public RestResult<List<AccountDTO>> listByUsername(String username, Integer page, Integer size) {
        List<AccountDTO> accountDTOList = accountService.listByUsername(username, page, size);
        int count = accountService.countByUsername(username);
        return RestResult.ok(accountDTOList).page(page, size, count);
    }

    @Override
    @Transactional(readOnly = true)
    public RestResult<List<AccountDTO>> listByRoleUkId(String roleUkId) {
        return RestResult.ok(accountService.listByRoleUkId(roleUkId));
    }

    @Override
    public RestResult<List<AccountDTO>> listByOrgUkId(String orgUkId) {
        return RestResult.ok(accountService.listByOrgUkId(orgUkId));
    }

}
